/**
 * Clase que maneja la Probabilidad de que un precio se repita dado un conjunto de datos. Esta clase ocupa la 
 * formula de distribucion normal, con media y varianza conocida. 
 */
package ws;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import org.orm.PersistentException;
import SOAPVO.LogSOAPVO;
import com.google.gson.Gson;

/**
 * @author kron623
 *
 */
public class combustibleSOAP {
	
	/**
	 * Calcula la media aritmetica de los valores en la base de datos
	 * @return media Valor de la media aritmetica, si se produce error retorna un negativo
	 * @throws PersistentException 
	 */
	private double media() throws PersistentException{
		double media=0;
		double sumatoria=0;
		orm.DAOFactory lDAOFactory = orm.DAOFactory.getDAOFactory();
		orm.Com_precio[] ormCom_precio = lDAOFactory.getCom_precioDAO().listCom_precioByQuery(null, null);
		int length = ormCom_precio.length;
		//se suman todos los valores
		for (int i = 0; i < length; i++) {
			sumatoria = ormCom_precio[i].getPre_precioDia() + sumatoria;
		}
		//calculo la media
		if (length ==0 ) {
			media = -1;
		}
		else{
			media = sumatoria / length; 
		}
		return media;
	}
	/**
	 * Calcula la varianza de todos los datos, si arroja errores retorna un -1
	 * @return varianza
	 * @throws PersistentException
	 */
	private double varianza() throws PersistentException{
		double varianza;
		double media = this.media();
		double sumatoria=0;
		orm.DAOFactory lDAOFactory = orm.DAOFactory.getDAOFactory();
		orm.Com_precio[] ormCom_precio = lDAOFactory.getCom_precioDAO().listCom_precioByQuery(null, null);
		int length = ormCom_precio.length;
		//se suman todos los valores
		for (int i = 0; i < length; i++) {
			sumatoria = Math.pow((ormCom_precio[i].getPre_precioDia() - media), 2) ;
		}
		if(length==0){
			varianza = -1; 
		}
		else{
			varianza = sumatoria / length;
		}
		return varianza;
	}
	/**
	 * retorna  la desviacion estandard de el valor respecto a la varianza y la media de los datos
	 * @param valor
	 * @return desEstandard Desviacion Estandar 
	 * @throws PersistentException
	 */
	private double desEstandard(double valor) throws PersistentException {
		double desEstandard = 0;
		desEstandard = Math.pow((this.media() - valor) / this.varianza(), 2 );
		
		return desEstandard;
	}

	/**
	 * Calcula la probabilidad de un precio conociendo sus N registros anteriores. estos datos se encuentran cargados en la base de datos
	 * @param precio Valor a estimar su probabilidad
	 * @return probabilidad Valor entre 0 y 1 que simboliza el porcentaje de acierto
	 * @throws PersistentException
	 */
	public double readProbabilidad(double precio) throws PersistentException {
		double tiempoInicial = System.currentTimeMillis();
		System.out.println(tiempoInicial);
		//defino las constantes de la formula
		double constantes = (1/(Math.sqrt(2 * Math.PI)));
		double desEstandard = this.desEstandard(precio);
		double probabilidad = constantes * (Math.pow(Math.E, desEstandard));
		double tiempoFinal = System.currentTimeMillis();
		System.out.println(tiempoFinal);
		this.createLog(tiempoInicial, tiempoFinal, precio, probabilidad);
		return probabilidad;
	}
	/**
	 * lee la lista de logs del sistema y los retorna como Json
	 * @return listaSerializada es la lista de los logs del sistema
	 * @throws PersistentException 
	 */
	public String readLog() throws PersistentException{
		
		String listaSerializada="";
		//creo una coleccion de 
		Collection<LogSOAPVO> coleccionLogSOAPVO = new ArrayList<LogSOAPVO>();
		orm.DAOFactory lDAOFactory = orm.DAOFactory.getDAOFactory();
		orm.Com_log[] ormCom_Logs = lDAOFactory.getCom_logDAO().listCom_logByQuery(null, null);
		int length = ormCom_Logs.length;
		for (int i = 0; i < length; i++) {
			LogSOAPVO objeto = LogSOAPVO.creaLogSOAPVO(ormCom_Logs[i]);
			coleccionLogSOAPVO.add(objeto);
		}
		Gson gson = new Gson();
		listaSerializada =  gson.toJson(coleccionLogSOAPVO);
		return listaSerializada;
		
	}
	/**
	 * Funcion que registra los estados en el log del sistema 
	 * @param tiempoInicial Cuando incia la aplicacion, contando la hora del sistema
	 * @param tiempoFinal Cuando termina la aplicacion, contando la hora del sistema
	 * @param parametro parametro pasado a la funcion que invoca al log
	 * @param resultado resultado del metodo que invoco a el log
	 * @return mensaje regresa string con exito o fracaso al ingresar el log
	 * @throws PersistentException
	 */	
	private String createLog(double tiempoInicial, double tiempoFinal, double parametro, double resultado) throws PersistentException{

		//creo un mensaje de retorno satisfactorio
		String horaactual = this.horaActual();
		System.out.println(horaactual);
		String mensaje = "";
		//calculo el tiempo que se demoro el metodo
		double tiempoTotal = ( tiempoFinal - tiempoInicial);
		//incio el factory para ingresar datos
		orm.DAOFactory lDAOFactory = orm.DAOFactory.getDAOFactory();
		//creo el objeto logDAO 
		orm.dao.Com_logDAO lormCom_logDAO = lDAOFactory.getCom_logDAO();
		//creo el objeto log para crear el dato
		orm.Com_log lormCom_log = lormCom_logDAO.createCom_log();
		//agrego los parametros
		lormCom_log.setLog_hora(horaactual);
		lormCom_log.setLog_resultado("" + resultado + "");
		lormCom_log.setLog_tiempo(tiempoTotal);
		lormCom_log.setParametro(parametro);
		//intento ingresar el objeto
		try {
			lormCom_logDAO.save(lormCom_log);
			mensaje = "exito";
		} catch (Exception e) {
			mensaje="error al agregar";
		}
		return mensaje;
	}
	/**
	 * Calcula la hora actual del sistema, y la formatea al estilo definido a la base de datos 
	 * HH:MM:SS 
	 * @return HORA la hora actual del sistema
	 */
	private String horaActual(){
        Calendar calendarioAhora = Calendar.getInstance();
        Date dateAhora = calendarioAhora.getTime();
        String hora = ""+ dateAhora.getHours() + "";
        String minutos = "" + dateAhora.getMinutes() + "";
        String segundos = "" + dateAhora.getSeconds() + "";
        String HORA = hora +":"+ minutos +":"+ segundos;
		return HORA;
	}
	
	
}
